﻿using cludg.Repository.NHibernate.Sessions;
using NHibernate;
using cludg.Infrastructure.Core.Logging;
using cludg.Repository.NHibernate;
using cludg.Web.Core.Notifications.Application;
using System;

namespace cludg.Web.NHibernate.Sessions
{
	public class NHibernateSessionController_PerHttpRequest : INHibernateSessionController, IDisposable
	{
		protected readonly ILogger Logger;
		protected readonly NHibernateController Controller;
		protected readonly IApplicationNotifier ApplicationNotifier;

		private ISession _session;

		public NHibernateSessionController_PerHttpRequest(
			NHibernateController controller,
			IApplicationNotifier applicationNotifier,
			ILogger logger)
		{
			Controller = controller;
			ApplicationNotifier = applicationNotifier;
			Logger = logger;

			ApplicationNotifier.EndRequest += ApplicationNotifierOnEndRequest;
		}

		private void ApplicationNotifierOnEndRequest(object sender, RequestEventArgs requestEventArgs)
		{
			if (_session == null)
				return;

			if (_session.IsConnected)
			{
				_session.Flush();
			}
			_session.Dispose();

			_session = null;
			Logger.Info("Dispose NHibernate session on end Http request");
		}

		protected void CheckSession()
		{
			if (_session == null || !_session.IsConnected)
			{
				_session = Controller.OpenSession();
				_session.FlushMode = FlushMode.Commit;
				Logger.Info("Open NHibernate session on Http request begin");
			}
		}

		public ISession Current
		{
			get
			{
				CheckSession();

				return _session;
			}
		}

		public void Reset()
		{
			_session = null;
			Logger.Info("NHibernate session reset");
		}

		public void Dispose()
		{
		}
	}
}
